home *** CD-ROM | disk | FTP | other *** search
- Subject: v15i005: Visual display of directory tree
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: uunet!ispi!jbayer
- Posting-number: Volume 15, Issue 5
- Archive-name: vtree
-
- Following is a shar archive containing a utility I have developed
- for Un*x systems. It displays the structure of a directory tree or
- filesystem. Unshar and read the README file, and the manual page.
- This was developed on a Xenix 386 system, but should work on most
- Un*x systems since it uses code from another public-domain program
- which already works on other systems. Credits are given in both
- the README file and the manual page.
-
- Enjoy.
-
- Jonathan Bayer
- Intelligent Software Products, Inc.
- 19 Virginia Ave.
- Rockville Centre, NY 11570
- uunet!ispi!jbayer (via uunet)
-
- [ As the documentation says, if you don't have the directory access
- routines, you should get them from your nearest archive site. -r$ ]
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # Makefile
- # README
- # customize.h
- # direct.c
- # hash.c
- # hash.h
- # patchlevel.h
- # vtree.1
- # vtree.c
- export PATH; PATH=/bin:$PATH
- if test -f 'Makefile'
- then
- echo shar: will not over-write existing file "'Makefile'"
- else
- cat << \SHAR_EOF > 'Makefile'
- # Build VTREE
- #
- # Define the type of system we're working with. Three
- # choices:
- #
- # 1. BSD Unix 4.2 or 4.3. Directory read support in the
- # standard library, so we don't have to do much. Select BSD.
- #
- # 2. System V. I depend on Doug Gwyn's directory reading
- # routines. They were posted to Usenet "comp.sources" early in
- # May 1987. They're worth the effort to get, if you don't have
- # them already. Select SYS_V. Be sure to define NLIB to be the
- # 'cc' option to include the directory library.
- #
- # 3. System III, or machines without any directory read
- # packages. I have a minimal kludge. Select SYS_III.
- #
-
- # Case 1:
- #SYS= -DBSD
- #NLIB=
-
- # Case 2:
- SYS= -DSYS_V
- NLIB= -lndir
-
- # Case 3:
- #SYS= -DSYS_III
- #NLIB=
-
-
- # Standard things you may wish to change:
- #
- # INSTALL directory to install vtree in
-
- INSTALL = /usr/local/bin
-
-
- # The following OPTIONS may be defined:
- #
- # LSTAT we have the lstat(2) system call (BSD only)
- # HSTATS print hashing statistics at end of run
- #
- # Define LSTAT, HSTATS here
-
- OPTIONS =
-
- # END OF USER-DEFINED OPTIONS
-
-
- CFLAGS= -O $(SYS) $(OPTIONS)
- SRCS= vtree.c hash.c direct.c \
- hash.h customize.h patchlevel.h
- OBJS= vtree.o hash.o
-
- vtree: $(OBJS)
- cc -o vtree $(CFLAGS) $(OBJS) $(NLIB)
-
- install: vtree
- cp vtree $(INSTALL)
- chown local $(INSTALL)/vtree
- chgrp pd $(INSTALL)/vtree
- chmod 755 $(INSTALL)/vtree
-
- clean:
- rm -f $(OBJS) vtree *~
-
- vtree.o: vtree.c direct.c hash.h customize.h patchlevel.h
-
- hash.o: hash.c hash.h customize.h patchlevel.h
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'README'
- then
- echo shar: will not over-write existing file "'README'"
- else
- cat << \SHAR_EOF > 'README'
- This is the first release of the VTREE (please pronounce this
- V-TREE, for "visual files") program. The program is designed to show
- the layout of a directory tree or filesystem. It has options to show
- the amount of storage being taken up in each directory, count the number
- of inodes, etc.
-
- VTREE is dependent on the UCB directory reading routines.
- Public-domain routines for System V have been released to the Usenet
- (comp.sources.unix) by Doug Gwyn (gwyn@brl.mil). If you don't have
- them, they're worth your trouble to get. Still, you may be able to use
- the System III configuration of the Makefile as a stopgap measure.
-
-
- The program was originally the program AGEF, written by David S.
- Hayes. As it stands now the hashing routines are untouched by myself,
- but most of the rest of the program is different. The System III
- routines are also his.
-
-
- I hope this program will be useful to you. If you find bugs in
- it or have any suggestions for improvements, I'd like to hear about
- them.
-
- Jonathan B. Bayer
- Intelligent Software Products, Inc.
- Rockville Centre, NY 11570
- Phone: (516) 766-2867
- usenet: uunet!ispi!root
-
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'customize.h'
- then
- echo shar: will not over-write existing file "'customize.h'"
- else
- cat << \SHAR_EOF > 'customize.h'
- /* agef
-
- SCCS ID @(#)customize.h 1.6 7/9/87
-
- This is the customizations file. It changes our ideas of
- how to read directories.
- */
-
- /*#define FLOAT_FORMAT "%d %#4.1fM" /* if your printf does %# */
- #define FLOAT_FORMAT "%d %4.1fM" /* if it doesn't do %# */
-
- #define NAMELEN 512 /* max size of a full pathname */
-
- #ifdef BSD
- # include <sys/dir.h>
- # define OPEN DIR
- # define READ struct direct
- # define NAME(x) ((x).d_name)
- #else
- #ifdef SYS_V
- /* Customize this. This is part of Doug Gwyn's package for */
- /* reading directories. If you've put this file somewhere */
- /* else, edit the next line. */
-
- # include <sys/dirent.h>
-
- # define OPEN struct direct
- # define READ struct dirent
- # define NAME(x) ((x).d_name)
- #else
- #ifdef SYS_III
- # define OPEN FILE
- # define READ struct direct
- # define NAME(x) ((x).d_name)
- # define INO(x) ((x).d_ino)
-
- # include "direct.c"
-
- #endif
- #endif
- #endif
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'direct.c'
- then
- echo shar: will not over-write existing file "'direct.c'"
- else
- cat << \SHAR_EOF > 'direct.c'
- /* direct.c
-
- SCCS ID @(#)direct.c 1.6 7/9/87
-
- *
- * My own substitution for the berkeley reading routines,
- * for use on System III machines that don't have any other
- * alternative.
- */
-
- #define NAMELENGTH 14
- #define opendir(name) fopen(name, "r")
- #define closedir(fp) fclose(fp)
-
- struct dir_entry { /* What the system uses internally. */
- ino_t d_ino;
- char d_name[NAMELENGTH];
- };
-
- struct direct { /* What these routines return. */
- ino_t d_ino;
- char d_name[NAMELENGTH];
- char terminator;
- };
-
-
- /*
- * Read a directory, returning the next (non-empty) slot.
- */
-
- READ *
- readdir(dp)
- OPEN *dp;
- {
- static READ direct;
-
- /* This read depends on direct being similar to dir_entry. */
-
- while (fread(&direct, sizeof(struct dir_entry), 1, dp) != 0) {
- direct.terminator = '\0';
- if (INO(direct) != 0)
- return &direct;
- };
-
- return (READ *) NULL;
- }
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'hash.c'
- then
- echo shar: will not over-write existing file "'hash.c'"
- else
- cat << \SHAR_EOF > 'hash.c'
- /* hash.c
-
- SCCS ID @(#)hash.c 1.6 7/9/87
-
- * Hash table routines for AGEF. These routines keep the program from
- * counting the same inode twice. This can happen in the case of a
- * file with multiple links, as in a news article posted to several
- * groups. The use of a hashing scheme was suggested by Anders
- * Andersson of Uppsala University, Sweden. (enea!kuling!andersa)
- */
-
- /* hash.c change history:
- 28 March 1987 David S. Hayes (merlin@hqda-ai.UUCP)
- Initial version.
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include "hash.h"
-
-
- static struct htable *tables[TABLES];
-
- /* These are for statistical use later on. */
- static int hs_tables = 0, /* number of tables allocated */
- hs_duplicates = 0, /* number of OLD's returned */
- hs_buckets = 0, /* number of buckets allocated */
- hs_extensions = 0, /* number of bucket extensions */
- hs_searches = 0,/* number of searches */
- hs_compares = 0,/* total key comparisons */
- hs_longsearch = 0; /* longest search */
-
-
- /*
- * This routine takes in a device/inode, and tells whether it's been
- * entered in the table before. If it hasn't, then the inode is added
- * to the table. A separate table is maintained for each major device
- * number, so separate file systems each have their own table.
- */
-
- h_enter(dev, ino)
- dev_t dev;
- ino_t ino;
- {
- static struct htable *tablep = (struct htable *) 0;
- register struct hbucket *bucketp;
- register ino_t *keyp;
- int i;
-
- hs_searches++; /* stat, total number of calls */
-
- /*
- * Find the hash table for this device. We keep the table pointer
- * around between calls to h_enter, so that we don't have to locate
- * the correct hash table every time we're called. I don't expect
- * to jump from device to device very often.
- */
- if (!tablep || tablep->device != dev) {
- for (i = 0; tables[i] && tables[i]->device != dev;)
- i++;
- if (!tables[i]) {
- tables[i] = (struct htable *) malloc(sizeof(struct htable));
- if (tables[i] == NULL) {
- perror("can't malloc hash table");
- return NEW;
- };
- /* bzero(tables[i], sizeof(struct htable)); */
- memset((char *) tables[i], '\0', sizeof (struct htable));
- tables[i]->device = dev;
- hs_tables++; /* stat, new table allocated */
- };
- tablep = tables[i];
- };
-
- /* Which bucket is this inode assigned to? */
- bucketp = &tablep->buckets[ino % BUCKETS];
-
- /*
- * Now check the key list for that bucket. Just a simple linear
- * search.
- */
- keyp = bucketp->keys;
- for (i = 0; i < bucketp->filled && *keyp != ino;)
- i++, keyp++;
-
- hs_compares += i + 1; /* stat, total key comparisons */
-
- if (i && *keyp == ino) {
- hs_duplicates++; /* stat, duplicate inodes */
- return OLD;
- };
-
- /* Longest search. Only new entries could be the longest. */
- if (bucketp->filled >= hs_longsearch)
- hs_longsearch = bucketp->filled + 1;
-
- /* Make room at the end of the bucket's key list. */
- if (bucketp->filled == bucketp->length) {
- /* No room, extend the key list. */
- if (!bucketp->length) {
- bucketp->keys = (ino_t *) calloc(EXTEND, sizeof(ino_t));
- if (bucketp->keys == NULL) {
- perror("can't malloc hash bucket");
- return NEW;
- };
- hs_buckets++;
- } else {
- bucketp->keys = (ino_t *)
- realloc(bucketp->keys,
- (EXTEND + bucketp->length) * sizeof(ino_t));
- if (bucketp->keys == NULL) {
- perror("can't extend hash bucket");
- return NEW;
- };
- hs_extensions++;
- };
- bucketp->length += EXTEND;
- };
-
- bucketp->keys[++(bucketp->filled)] = ino;
- return NEW;
- }
-
-
- /* Buffer statistics functions. Print 'em out. */
-
- #ifdef HSTATS
- void
- h_stats()
- {
- fprintf(stderr, "\nHash table management statistics:\n");
- fprintf(stderr, " Tables allocated: %d\n", hs_tables);
- fprintf(stderr, " Buckets used: %d\n", hs_buckets);
- fprintf(stderr, " Bucket extensions: %d\n\n", hs_extensions);
- fprintf(stderr, " Total searches: %d\n", hs_searches);
- fprintf(stderr, " Duplicate keys found: %d\n", hs_duplicates);
- if (hs_searches)
- fprintf(stderr, " Average key search: %d\n",
- hs_compares / hs_searches);
- fprintf(stderr, " Longest key search: %d\n", hs_longsearch);
- fflush(stderr);
- }
-
- #endif
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'hash.h'
- then
- echo shar: will not over-write existing file "'hash.h'"
- else
- cat << \SHAR_EOF > 'hash.h'
- /* Defines for the agef hashing functions.
-
- SCCS ID @(#)hash.h 1.6 7/9/87
- */
-
- #define BUCKETS 257 /* buckets per hash table */
- #define TABLES 50 /* hash tables */
- #define EXTEND 100 /* how much space to add to a bucket */
-
- struct hbucket {
- int length; /* key space allocated */
- int filled; /* key space used */
- ino_t *keys;
- };
-
- struct htable {
- dev_t device; /* device this table is for */
- struct hbucket buckets[BUCKETS]; /* the buckets of the table */
- };
-
- #define OLD 0 /* inode was in hash already */
- #define NEW 1 /* inode has been added to hash */
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'patchlevel.h'
- then
- echo shar: will not over-write existing file "'patchlevel.h'"
- else
- cat << \SHAR_EOF > 'patchlevel.h'
- /* Patchlevel for VTREE
-
- */
-
- #define PATCHLEVEL V1.0
- #define VERSION "VTREE 1.0 4/26/88\n"
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'vtree.1'
- then
- echo shar: will not over-write existing file "'vtree.1'"
- else
- cat << \SHAR_EOF > 'vtree.1'
- .TH VTREE 1 local
- .SH NAME
- vtree \- print a visual tree of a directory structure
- .SH SYNOPSIS
- .B vtree
- [ \-d] [ \-h # ] [ \-i ] [ \-s ] [ \-q ] [ \-v ] [ \-V ]
- .SH DESCRIPTION
- .IP
- Vtree is a program which scans directories/filesystems and displays the structure on the
- standard output. Normally it will ignore duplicate inodes.
- .IP "\-d "
- Instructs the program to include the duplicate inodes in the totals.
- .PP
- .IP "\-h #"
- Specifies how many levels down to display.
- .PP
- .IP \-i
- displays the number of inodes (excluding directories) in each directory
- .PP
- .IP \-s
- Instructs the program to continue counting inodes and file sizes when it
- has exceeded the levels specified.
- .PP
- .IP \-t
- Displays totals at the end of the report
- .PP
- .IP \-q
- Quick display. No totals of any kind are kept.
- .PP
- .IP \-v
- Visual display. Normally the program displays one directory on a line,
- indenting lines to indicate subdirectories. The visual display builds
- a tree on the screen showing the actual directory structure. This method
- of display excludes any totals other than the final totals.
- .PP
- .IP \-V
- Shows current version. Specifying 2 Vs (-VV) will also show all options in
- force.
- .SH AUTHOR
- Jonathan B. Bayer
- .PP
- Intelligent Software Products, Inc.
- .PP
- Rockville Centre, NY 11570
- .SH ACKNOWLEDGMENTS
- The program uses the directory routines written and released to the
- public domain by Doug Gwyn.
- The program is originally based on a program called AGEF written by
- David S. Hayes.
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'vtree.c'
- then
- echo shar: will not over-write existing file "'vtree.c'"
- else
- cat << \SHAR_EOF > 'vtree.c'
- /* vtree
-
- +=======================================+
- | This program is in the public domain. |
- +=======================================+
-
- This program shows the directory structure of a filesystem or
- part of one. It also shows the amount of space taken up by files
- in each subdirectory.
-
- Call via
-
- vtree fn1 fn2 fn3 ...
-
- If any of the given filenames is a directory (the usual case),
- vtree will recursively descend into it, and the output line will
- reflect the accumulated totals for all files in the directory.
-
- This program is based upon "agef" written by David S. Hayes at the
- Army Artificial Intelligence Center at the Pentagon.
-
- This program is dependent upon the new directory routines written by
- Douglas A. Gwyn at the US Army Ballistic Research Laboratory at the
- Aberdeen Proving Ground in Maryland.
- */
-
- #include "patchlevel.h"
-
- #include <ctype.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/param.h>
- #include <stdio.h>
-
- #include "customize.h"
- #include "hash.h"
-
- #define SAME 0 /* for strcmp */
- #define BLOCKSIZE 512 /* size of a disk block */
-
- #define K(x) ((x + 1023)/1024) /* convert stat(2) blocks into
- * k's. On my machine, a block
- * is 512 bytes. */
-
- #define TRUE 1
- #define FALSE 0
- #define V_CHAR "|" /* Vertical character */
- #define H_CHAR "-" /* Horizontal character */
- #define A_CHAR ">" /* Arrow char */
- #define T_CHAR "+" /* Tee char */
- #define L_CHAR "\\" /* L char, bottom of a branch */
-
- #define MAX_COL_WIDTH 15
- #define MAX_V_DEPTH 256 /* max depth for visual display */
-
- int indent = 0, /* current indent */
- depth = 9999, /* max depth */
- cur_depth = 0,
- sum = FALSE, /* sum the subdirectories */
- dup = FALSE, /* use duplicate inodes */
- cnt_inodes = FALSE, /* count inodes */
- quick = FALSE; /* quick display */
- visual = FALSE; /* visual display */
- version = 0; /* = 1 display version, = 2 show options */
- sub_dirs[MAX_V_DEPTH];
-
- struct stat stb; /* Normally not a good idea, but */
- /* this structure is used through- */
- /* out the program */
-
- extern char *optarg; /* from getopt(3) */
- extern int optind,
- opterr;
-
-
- char *Program; /* our name */
- short sw_follow_links = 1; /* follow symbolic links */
- short sw_summary; /* print Grand Total line */
-
- int total_inodes, inodes; /* inode count */
- long total_sizes, sizes; /* block count */
-
- char topdir[NAMELEN]; /* our starting directory */
-
-
- /*
- * We ran into a subdirectory. Go down into it, and read everything
- * in there.
- */
- int indented = FALSE; /* These had to be global since they */
- int last_indent = 0; /* determine what gets displayed during */
- /* the visual display */
-
- down(subdir)
- char *subdir;
- {
- OPEN *dp; /* stream from a directory */
- OPEN *opendir ();
- char cwd[NAMELEN];
- READ *file; /* directory entry */
- READ *readdir ();
- int i;
- struct stat stb;
-
- if ( (cur_depth == depth) && (!sum) )
- return;
-
- /* display the tree */
-
- if (cur_depth < depth) {
- if (visual) {
- if (!indented) {
- for (i = 1; i <cur_depth; i++) {
- if (sub_dirs[i]) {
- printf("%*s%s ",MAX_COL_WIDTH-4," ",V_CHAR);
- }
- else printf("%*s ",MAX_COL_WIDTH-3," ");
- }
- if (cur_depth>0) {
- if (sub_dirs[cur_depth] == 0) {
- printf("%*s%s%s%s ",MAX_COL_WIDTH-4," ",L_CHAR,H_CHAR,A_CHAR);
- }
- else printf("%*s%s%s%s ",MAX_COL_WIDTH-4," ",T_CHAR,H_CHAR,A_CHAR);
- }
- } else {
- for (i = 1; i<MAX_COL_WIDTH-last_indent-3; i++)
- printf("%s",H_CHAR);
- printf("%s%s%s ",T_CHAR,H_CHAR,A_CHAR);
- }
-
- /* This will only happen on the first entry into this routine */
-
- if (strlen(subdir) > MAX_COL_WIDTH - 4) {
- printf("%s\n",subdir);
- printf("%s ",&subdir[strlen(subdir)-MAX_COL_WIDTH+5]);
- last_indent = MAX_COL_WIDTH - 4;
- }
- else {
- printf("%s ",subdir);
- last_indent = strlen(subdir)+1;
- }
- indented = TRUE;
- }
- else printf("%*s%s",indent," ",subdir);
- }
-
- /* open subdirectory */
-
- if ((dp = opendir(subdir)) == NULL) {
- printf(" - can't read %s\n", subdir);
- indented = FALSE;
- return;
- }
-
- cur_depth++;
- indent+=3;
-
- getcwd(cwd, sizeof(cwd)); /* remember where we are */
- chdir(subdir); /* go into subdir */
- if ( (!quick) && (!visual) ) {
-
- /* accumulate total sizes and inodes in current directory */
-
- for (file = readdir(dp); file != NULL; file = readdir(dp))
- if (strcmp(NAME(*file), "..") != SAME)
- get_data(NAME(*file),FALSE);
-
- if (cur_depth<depth) {
- if (cnt_inodes) printf(" %d",inodes);
- printf(" : %ld\n",sizes);
- total_sizes += sizes;
- total_inodes += inodes;
- sizes = 0;
- inodes = 0;
- }
- rewinddir(dp);
- } else if (!visual) printf("\n");
-
- if (visual) {
-
- /* count subdirectories */
-
- for (file = readdir(dp); file != NULL; file = readdir(dp)) {
- if ( (strcmp(NAME(*file), "..") != SAME) &&
- (strcmp(NAME(*file), ".") != SAME) ) {
- if (chk_4_dir(NAME(*file))) {
- sub_dirs[cur_depth]++;
- }
- }
- }
- rewinddir(dp);
- }
-
- /* go down into the subdirectory */
-
- for (file = readdir(dp); file != NULL; file = readdir(dp)) {
- if ( (strcmp(NAME(*file), "..") != SAME) &&
- (strcmp(NAME(*file), ".") != SAME) ) {
- if (chk_4_dir(NAME(*file)))
- sub_dirs[cur_depth]--;
- get_data(NAME(*file),TRUE);
- }
- }
-
- if ( (!quick) && (!visual) ) {
-
- /* print totals */
-
- if (cur_depth == depth) {
- if (cnt_inodes) printf(" %d",inodes);
- printf(" : %ld\n",sizes);
- total_sizes += sizes;
- total_inodes += inodes;
- sizes = 0;
- inodes = 0;
- }
- } else if (visual && indented) {
- printf("\n");
- indented = FALSE;
- }
-
- indent-=3;
- sub_dirs[cur_depth] = 0;
- cur_depth--;
-
- chdir(cwd); /* go back where we were */
- closedir(dp); /* shut down the directory */
- } /* down */
-
-
-
- int chk_4_dir(path)
- char *path;
- {
- if (is_directory(path)) return TRUE;
- else return FALSE;
-
- } /* chk_4_dir */
-
-
-
- /* Is the specified path a directory ? */
-
- int is_directory(path)
- char *path;
- {
-
- #ifdef LSTAT
- if (sw_follow_links)
- stat(path, &stb); /* follows symbolic links */
- else
- lstat(path, &stb); /* doesn't follow symbolic links */
- #else
- stat(path, &stb);
- #endif
-
- if ((stb.st_mode & S_IFMT) == S_IFDIR)
- return TRUE;
- else return FALSE;
- } /* is_directory */
-
-
-
- /*
- * Get the aged data on a file whose name is given. If the file is a
- * directory, go down into it, and get the data from all files inside.
- */
-
- get_data(path,cont)
- char *path;
- int cont;
- {
- /* struct stat stb; */
- int i;
-
- if (cont) {
- if (is_directory(path))
- down(path);
- }
- else {
- if (is_directory(path)) return;
-
- /* Don't do it again if we've already done it once. */
-
- if ( (h_enter(stb.st_dev, stb.st_ino) == OLD) && (!dup) )
- return;
- inodes++;
- sizes+= K(stb.st_size);
- }
- } /* get_data */
-
-
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int i,
- j,
- err = FALSE;
- int option;
- int user_file_list_supplied = 0;
-
- Program = *argv; /* save our name for error messages */
-
- /* Pick up options from command line */
-
- while ((option = getopt(argc, argv, "dh:istqvV")) != EOF) {
- switch (option) {
- case 'h': depth = atoi(optarg);
- while (*optarg) {
- if (!isdigit(*optarg)) {
- err = TRUE;
- break;
- }
- optarg++;
- }
- break;
- case 'd': dup = TRUE;
- break;
- case 'i': cnt_inodes = TRUE;
- break;
- case 's': sum = TRUE;
- break;
- case 't': sw_summary = TRUE;
- break;
- case 'q': quick = TRUE;
- dup = FALSE;
- sum = FALSE;
- cnt_inodes = FALSE;
- break;
- case 'v': visual = TRUE;
- break;
- case 'V': version++;
- break;
- default: err = TRUE;
- }
- if (err) {
- fprintf(stderr,"%s: [ -d ] [ -h # ] [ -i ] [ -s ] [ -q ] [ -v ] [ -V ]\n",Program);
- fprintf(stderr," -d count duplicate inodes\n");
- fprintf(stderr," -h # height of tree to look at\n");
- fprintf(stderr," -i count inodes\n");
- fprintf(stderr," -s include subdirectories not shown due to -h option\n");
- fprintf(stderr," -t totals at the end\n");
- fprintf(stderr," -q quick display, no counts\n");
- fprintf(stderr," -v visual display\n");
- fprintf(stderr," -V show current version\n");
- fprintf(stderr," (2 Vs shows specified options)\n");
- exit(-1);
- }
-
- }
-
- if (version > 0 ) {
- printf("%s",VERSION);
- if (version>1) {
- printf("Tree height: %d\n",depth);
- if (dup) printf("Include duplicate inodes\n");
- if (cnt_inodes) printf("Count inodes\n");
- if (sum) printf("Include unseen subdirectories in totals\n");
- if (sw_summary) printf("Print totals at end\n");
- if (quick) printf("Quick display only\n");
- if (visual) printf("Visual tree\n");
- }
- }
-
- /* If user didn't specify targets, inspect current directory. */
-
- if (optind >= argc) {
- user_file_list_supplied = 0;
- } else {
- user_file_list_supplied = 1;
- }
-
- getcwd(topdir, sizeof (topdir)); /* find out where we are */
-
- /* Zero out grand totals */
- total_inodes = total_sizes = 0;
- /* Zero out sub_dirs */
- for (i=0; i<=MAX_V_DEPTH; i++) {
- sub_dirs[i] = 0;
- }
-
- /* Inspect each argument */
- for (i = optind; i < argc || (!user_file_list_supplied && i == argc); i++) {
- cur_depth = inodes = sizes = 0;
-
- chdir(topdir); /* be sure to start from the same place */
- get_data(user_file_list_supplied?argv[i] : topdir, TRUE);/* this may change our cwd */
-
- total_inodes += inodes;
- total_sizes += sizes;
- }
-
- if (sw_summary) {
- printf("\n\nTotal space used: %ld\n",total_sizes);
- if (cnt_inodes) printf("Total inodes: %d\n",inodes);
- }
-
- #ifdef HSTATS
- fflush(stdout);
- h_stats();
- #endif
-
- exit(0);
- } /* main */
-
-
- SHAR_EOF
- fi # end of overwriting check
- # End of shell archive
- exit 0
-
-
-